#include<boost/asio/io_service.hpp>  
#include<boost/asio/ip/tcp.hpp>  
#include<boost/bind.hpp>  
#include<boost/shared_ptr.hpp>  
#include<boost/enable_shared_from_this.hpp>  
#include<string>  
#include<iostream>  
#include<boost/asio/streambuf.hpp>  
#include<boost/asio/placeholders.hpp>  
#include<boost/asio.hpp> 

using boost::asio::ip::tcp;  
using boost::asio::ip::address;  

char test_cmd[10];

class client : public boost::enable_shared_from_this<client> {  
public:  
    client(boost::asio::io_service &io_service, tcp::endpoint &endpoint)  
        : io_service_(io_service), socket_(io_service), endpoint_(endpoint)  
    {  
    }  
  
    void start() {  
        socket_.async_connect(endpoint_,  
            boost::bind(&client::handle_connect,  
            shared_from_this(),  
            boost::asio::placeholders::error));  
    }  
  
private:  
    void handle_connect(const boost::system::error_code &error) {  
        if (error) {  
            if (error.value() != boost::system::errc::operation_canceled) {  
                std::cerr << boost::system::system_error(error).what() << std::endl;  
            }  
  
            socket_.close();  
            return;  
        }  
  
        static tcp::no_delay option(true);  
        socket_.set_option(option);  
  		
		if(!strcmp(test_cmd, "key_test"))
        	strcpy(buf, "key_test\n");  
		else if(!strcmp(test_cmd, "audio_test"))
       		strcpy(buf, "audio_test\n");  
printf("zewen---> [FUNC]%s [LINE]:%d buf:%s\n", __FUNCTION__, __LINE__, buf);
        boost::asio::async_write(socket_,  
            boost::asio::buffer(buf, strlen(buf)),  
            boost::bind(&client::handle_write,  
            shared_from_this(),  
            boost::asio::placeholders::error,  
            boost::asio::placeholders::bytes_transferred));  
    }  
  
    void handle_write(const boost::system::error_code& error, size_t bytes_transferred) {  
        memset(buf, sizeof(buf), 0);  
        boost::asio::async_read_until(socket_,  sbuf,"\n",  
            boost::bind(&client::handle_read,  
            shared_from_this(),  
            boost::asio::placeholders::error,  
            boost::asio::placeholders::bytes_transferred));  
    }  
  
    void handle_read(const boost::system::error_code& error, size_t bytes_transferred) {  
		boost::asio::streambuf::const_buffers_type cbt = sbuf.data();
		std::string sbuf_data(boost::asio::buffers_begin(cbt), boost::asio::buffers_end(cbt));
        //std::cout << buf << std::endl;  
        std::cout << "zewen:" << std::endl;  
        std::cout << sbuf_data << std::endl;  
		if(sbuf_data == "key_pass\n")
			printf("zewen---> [FUNC]%s [LINE]:%d key_test passed!\n", __FUNCTION__, __LINE__);
		else if(sbuf_data == "key_failed\n")
			printf("zewen---> [FUNC]%s [LINE]:%d key_test failed!!!\n", __FUNCTION__, __LINE__);
    }  
  
private:  
    boost::asio::io_service &io_service_;  
    tcp::socket socket_;  
    tcp::endpoint &endpoint_;  
    char buf[1024];  
    boost::asio::streambuf sbuf;  
};  
  
typedef boost::shared_ptr<client> client_ptr;  
  
int main(int argc, char* argv[])  
{  
	if (argc < 2) {
		std::cerr << "Run as: " << argv[0] << " \"key_test\\n or audio_test\\n\"" << std::endl;
		exit(1);
	}

	strcpy(test_cmd, argv[1]);
	if(!strcmp(test_cmd, "key_test"))
			printf("zewen---> [FUNC]%s [LINE]:%d =======\n", __FUNCTION__, __LINE__);
	printf("zewen---> [FUNC]%s [LINE]:%d test_cmd:%s\n", __FUNCTION__, __LINE__, test_cmd);

    boost::asio::io_service io_service;  
    //tcp::endpoint endpoint(address::from_string("127.0.0.1"), 1000);  
    tcp::endpoint endpoint(address::from_string("192.168.1.105"), 1000);  

	std::string sss = {"hello\n"};
	if(sss == "hello\n")
		printf("zewen---> [FUNC]%s [LINE]:%d =========\n", __FUNCTION__, __LINE__);
	else
		printf("zewen---> [FUNC]%s [LINE]:%d nnnnnnnnn\n", __FUNCTION__, __LINE__);
  
    client_ptr new_session(new client(io_service, endpoint));  
    new_session->start();  
    io_service.run();  
    std::string ss;  
	printf("zewen---> [FUNC]%s [LINE]:%d\n", __FUNCTION__, __LINE__);
    std::cin >> ss;  
    return 0;  
}  
